const std = @import("std");
const zon = std.zon;
const Allocator = std.mem.Allocator;

pub const Rule = struct {
    scidr: []const u8,
    dport: u16,
    proto: []const u8,
    action: []const u8,
};

const FirewallConfig = struct {
    rules: []const Rule,

    pub fn deinit(self: FirewallConfig, allocator: Allocator) void {
        for (self.rules) |rule| {
            allocator.free(rule.scidr);
            allocator.free(rule.proto);
            allocator.free(rule.action);
        }
        allocator.free(self.rules);
    }
};

fn readFile(allocator: std.mem.Allocator, file_path: []const u8) ![:0]const u8 {
    const cwd = std.fs.cwd();
    const file = try cwd.openFile(file_path, .{});
    defer file.close();

    const file_size = try file.getEndPos();
    const buffer = try allocator.allocSentinel(u8, file_size, 0);
    _ = try file.readAll(buffer);
    return buffer;
}

pub fn get(allocator: std.mem.Allocator) !FirewallConfig {
    var arena = std.heap.ArenaAllocator.init(allocator);
    defer arena.deinit();

    const arena_allocator = arena.allocator();
    const file_path = "ZephyrFirewall/firewall.zon";
    const file_content = try readFile(arena_allocator, file_path);

    var diag: zon.parse.Diagnostics = .{};
    defer diag.deinit(allocator);
    const parsed = zon.parse.fromSlice(
        FirewallConfig,
        allocator,
        file_content,
        &diag,
        .{ .free_on_error = true },
    ) catch |err| {
        std.debug.print("Parse status: {any}\n", .{diag});
        return err;
    };
    // defer parsed.deinit(allocator);

    return parsed;
}
